/** \file chatgpt.c 
 *  \brief chatgpt
 */
#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <string>

#include "Rk_wifi.h"
#include "rk_mpi_amix.h"
#include "speechnls.h" 

#include "het_ringbuf.h" 
#include "het_chatgpt.h"  // <-- 唯一必须包含的头文件
RingBuffer audioPlayBuf;
RingBuffer audioRecBuf;
RK_BOOL global_run = RK_TRUE, ao_run = RK_TRUE , in_play = RK_FALSE, in_asr = RK_FALSE, in_tts = RK_FALSE, in_query = RK_FALSE, in_oath = RK_FALSE;
RK_U32 ai_run = 0, rec_ready = 2;//为了支持语音唤醒

void signal_handler_int(int signo) {
  std::cout << "\r\nget interrupt mesg\r\n" << std::endl;
  global_run = RK_FALSE;
  cmd_exit();
}
void signal_handler_quit(int signo) {
  std::cout << "\r\nget quit mesg\r\n" << std::endl;
  global_run = RK_FALSE;
  cmd_exit();
}

#define HET_AI_VERSION "v1.0.6"


SAMPLE_MPI_CTX_S g_ctx;

void exec_command(char cmdline[], char recv_buff[], int len)
{
	//HET_LOGI("[BT_DEBUG] execute: %s\n", cmdline);

	FILE *stream = NULL;
	char *tmp_buff = recv_buff;

	memset(recv_buff, 0, len);

	if ((stream = popen(cmdline, "r")) != NULL) {
		while (fgets(tmp_buff, len, stream)) {
			//HET_LOGI("tmp_buf[%d]: %s\n", strlen(tmp_buff), tmp_buff);
			tmp_buff += strlen(tmp_buff);
			len -= strlen(tmp_buff);
			if (len <= 1)
				break;
		}

		//HET_LOGI("[BT_DEBUG] execute_r: %s \n", recv_buff);
		pclose(stream);
	} else
		HET_LOGE("[popen] error: %s\n", cmdline);
}
int wpa_wifi_running_getConnectionInfo(RK_WIFI_INFO_Connection_s* pInfo)
{
	int ret = -1;
	FILE *fp = NULL;
	char line[512];
	char *value, *orgs;
	HET_LOGD("%s: enter\n", __func__);

	if (pInfo == NULL)
		return false;
	HET_LOGD("%s: %d\n", __func__, __LINE__);

	if (remove("/tmp/status.tmp"))
		HET_LOGE("remove /tmp/status.tmp failed!\n");
	system("wpa_cli -iwlan0 status > /tmp/status.tmp");
	HET_LOGD("%s: %d\n", __func__, __LINE__);

	// check wpa is running first
	memset(line, 0, sizeof(line));
	exec_command((char*)"cat /tmp/status.tmp", line, 512);
	HET_LOGD("status.tmp: %s\n", line);
	HET_LOGD("%s: %d\n", __func__, __LINE__);

	memset(line, 0, sizeof(line));
	exec_command((char*)"wpa_cli -iwlan0 status", line, 512);
	HET_LOGD("wpa_cli status: %s\n", line);
	HET_LOGD("%s: %d\n", __func__, __LINE__);

	fp = fopen("/tmp/status.tmp", "r");
	if (!fp) {
		HET_LOGE("fopen /tmp/status.tmp failed!\n");
		return ret;
	}
	HET_LOGD("%s: %d\n", __func__, __LINE__);

	memset(pInfo, 0, sizeof(RK_WIFI_INFO_Connection_s));
	memset(line, 0, sizeof(line));
	while (fgets(line, sizeof(line) - 1, fp)) {
		if (line[strlen(line) - 1] == '\n')
			line[strlen(line) - 1] = '\0';

		if (0 == strncmp(line, "address", 7)) {
			value = strchr(line, '=');
			if (value && strlen(value) > 0) {
				strncpy(pInfo->mac_address, value + 1, sizeof(pInfo->mac_address));
				ret = 0;
			}
		}
	}
	HET_LOGD("%s: %d\n", __func__, __LINE__);
	fclose(fp);
	return ret;
}


pthread_mutex_t curl_agent_lock;
pthread_mutex_t curl_buf_lock;
pthread_mutex_t play_lock;
pthread_mutex_t curl_lock;
pthread_mutex_t token_lock;
int rkchatgpt_init(void) {
	RK_S32 result;
	RK_S32 s32PeriodSize = 1024;
	RK_S32 s32loopCnt = -1;
	memset(&audioRecBuf,0,sizeof(RingBuffer));
	memset(&audioPlayBuf,0,sizeof(RingBuffer));
	rb_createRingBuffer(&audioRecBuf,(char *)"rec",640*1024,(RK_CACHE_TYPE_MODE_E)0);
	rb_createRingBuffer(&audioPlayBuf,(char *)"play",2*640*1024,(RK_CACHE_TYPE_MODE_E)0);
    rb_setMinValue(&audioRecBuf,100);
    rb_setMinValue(&audioPlayBuf,100);
	HET_LOGI("het version %s !!!\r\n",HET_AI_VERSION);
	memset(&g_ctx,0,sizeof(SAMPLE_MPI_CTX_S));
	g_ctx.ai.s32DevId = AI_DEV_ID;
	g_ctx.ai.s32ChnId = AI_CHN_ID;
	// 只有左声道数据有效
	g_ctx.ai.s32ChnCnt = 1;
	g_ctx.ai.s32ChnSampleRate = 16000;
	g_ctx.ai.s32BitWidth = AUDIO_BIT_WIDTH_16;
	g_ctx.ai.s32DeviceSampleRate = 16000;
	// 要作回采，使用双通道
	g_ctx.ai.s32DeviceChannel = 2;	
	g_ctx.ai.cardName = (RK_CHAR *)"hw:0,0";
	g_ctx.ai.s32PeriodCount = 4;
	g_ctx.ai.s32PeriodSize = 1024;
    g_ctx.ai.saveDataFile = RK_NULL;
    g_ctx.ai.dstFilePath = RK_NULL;
    g_ctx.ai.s32RecognizerEnable = 0;
    g_ctx.ai.s32AedEnable       = 1;// 默认是识别状态
    g_ctx.ai.fSnrDB       = 10.0f;// 默认是识别状态
    g_ctx.ai.fLsdDB       = -25.0f;// 默认是识别状态
    g_ctx.ai.s32BcdEnable       = 0;
    g_ctx.ai.s32BuzEnable       = 0;
    g_ctx.ai.s32GbsEnable       = 0;
    g_ctx.ai.s32VqeGapMs        = 16;
    g_ctx.ai.s32VqeEnable       = 0;
    g_ctx.ai.pVqeCfgPath        = "/userdata/config_aivqe_gpt.json";
    g_ctx.ai.s32DumpAlgo        = 0;
	g_ctx.ai.s32AedPolicy          = 0;
	
    g_ctx.ai.s32AedAcousticRecCountMax = 2;// 录音高信噪最大值
	g_ctx.ai.s32AedSaveRecCountMin= 15;// 录音可以保存的最小值
    g_ctx.ai.s32AedAcousticMuteCountMax=15;// 静音低信噪最大值
	g_ctx.ai.s32AedAcousticEndCountMax=100;// 静音多久结束识别


    g_ctx.ai.s32SetVolumeCurve  = AUDIO_CURVE_LOGARITHM;
    g_ctx.ai.s32SetVolume       = 100;
    g_ctx.ai.s32SetMute         = 0;
    g_ctx.ai.s32SetTrackMode    = AUDIO_TRACK_FRONT_LEFT;//AUDIO_TRACK_FRONT_LEFT 关掉回采，只采左声道
    g_ctx.ai.s32SetFadeRate     = 0;
    g_ctx.ai.s32GetVolume       = 1;
    g_ctx.ai.s32GetMute         = 1;
    g_ctx.ai.s32GetTrackMode    = 1;
	
	g_ctx.ao.s32DevId = AO_DEV_ID;
	g_ctx.ao.s32ChnId = AO_CHN_ID;
	g_ctx.ao.s32DeviceSampleRate = 16000;
	g_ctx.ao.s32ChnSampleRate = 16000;
	g_ctx.ao.s32BitWidth = AUDIO_BIT_WIDTH_16;
	g_ctx.ao.s32DeviceChannel = 2;	
	g_ctx.ao.s32SetVolumeCurve = AUDIO_CURVE_LOGARITHM;
    g_ctx.ao.s32SetVolume       = 100;
	g_ctx.ao.cardName=(RK_CHAR *)"hw:0,0";
	g_ctx.ao.s32SetMute = 0;
	g_ctx.ao.s32PeriodSize=1280;
    g_ctx.ao.readDataFile = RK_NULL;
    g_ctx.ao.dstFilePath = (RK_CHAR *)"/userdata";
	g_ctx.ao.s32SetTrackMode = AUDIO_TRACK_OUT_STEREO;
	// 以下参数无特殊需求，无需变动，保持默认值即可
    g_ctx.ao.s32DataReadEnable  = 0;//aiAttr.u32EXFlag
	g_ctx.ao.s32PeriodCount=2;//aiAttr.u32FrmNum
	g_ctx.ao.s32ChnCnt = 1;//aiAttr.u32ChnCnt

	g_ctx.amix[0][0] = (char*)"0";//"I2STDM Digital Loopback Mode";
	g_ctx.amix[0][1] = (char*)"Disabled";

	g_ctx.amix[1][0] = (char*)"1";//"ADC MIC Left Gain";
	g_ctx.amix[1][1] = (char*)"2";

	g_ctx.amix[2][0] = (char*)"2";//"ADC MIC Right Gain";
	g_ctx.amix[2][1] = (char*)"1";

	g_ctx.amix[3][0] = (char*)"3";//"ADC ALC Left Volume";
	g_ctx.amix[3][1] = (char*)"7";

	g_ctx.amix[4][0] = (char*)"4";//"ADC ALC Right Volume";
	g_ctx.amix[4][1] = (char*)"11";

	g_ctx.amix[5][0] = (char*)"5";//"ADC Digital Left Volume";
	g_ctx.amix[5][1] = (char*)"195";

	g_ctx.amix[6][0] = (char*)"6";//"ADC Digital Right Volume";
	g_ctx.amix[6][1] = (char*)"195";

	g_ctx.amix[7][0] = (char*)"7";//"ADC HPF Cut-off";
	g_ctx.amix[7][1] = (char*)"Off";

	g_ctx.amix[8][0] = (char*)"8";//"ALC AGC Left Volume";
	g_ctx.amix[8][1] = (char*)"12";

	g_ctx.amix[9][0] = (char*)"9";//"ALC AGC Right Volume";
	g_ctx.amix[9][1] = (char*)"12";

	g_ctx.amix[10][0] = (char*)"10";//"ALC AGC Left Max Volume";
	g_ctx.amix[10][1] = (char*)"7";

	g_ctx.amix[11][0] = (char*)"11";//"ALC AGC Right Max Volume";
	g_ctx.amix[11][1] = (char*)"7";

	g_ctx.amix[12][0] = (char*)"12";//"ALC AGC Left Min Volume";
	g_ctx.amix[12][1] = (char*)"0";

	g_ctx.amix[13][0] = (char*)"13";//"ALC AGC Right Min Volume";
	g_ctx.amix[13][1] = (char*)"0";

	g_ctx.amix[14][0] = (char*)"14";//"AALC AGC Left Switch";
	g_ctx.amix[14][1] = (char*)"Off";

	g_ctx.amix[15][0] = (char*)"15";//"ALC AGC Right Switch";
	g_ctx.amix[15][1] = (char*)"Off";

	g_ctx.amix[16][0] = (char*)"16";//"AGC Left Approximate Sample Rate";
	g_ctx.amix[16][1] = (char*)"96KHz";

	g_ctx.amix[17][0] = (char*)"17";//"AGC Right Approximate Sample Rate";
	g_ctx.amix[17][1] = (char*)"96KHz";

	g_ctx.amix[18][0] = (char*)"18";//"ADC Mode";
	g_ctx.amix[18][1] = (char*)"DiffadcLR";

	g_ctx.amix[19][0] = (char*)"19";//"ADC MICBIAS Voltage";
	g_ctx.amix[19][1] = (char*)"VREFx0_9";

	g_ctx.amix[20][0] = (char*)"20";//"ADC Main MICBIAS";
	g_ctx.amix[20][1] = (char*)"On";

	g_ctx.amix[21][0] = (char*)"21";//"ADC MIC Left Switch";
	g_ctx.amix[21][1] = (char*)"Work";

	g_ctx.amix[22][0] = (char*)"22";//"ADC MIC Right Switch ";
	g_ctx.amix[22][1] = (char*)"Work";

	g_ctx.amix[23][0] = (char*)"23";//"DAC LINEOUT Volume ";
	g_ctx.amix[23][1] = (char*)"20";

	g_ctx.amix[24][0] = (char*)"24";//"DAC HPMIX Volume";
	g_ctx.amix[24][1] = (char*)"1";

	g_ctx.amix[25][0] = (char*)"25";//"DAC Control Manually";
	g_ctx.amix[25][1] = (char*)"Off";

	RK_WIFI_INFO_Connection_s pInfo;
	if(wpa_wifi_running_getConnectionInfo(&pInfo) == 0){
		update_clife_mac(pInfo.mac_address);
	}
	pthread_mutex_init(&curl_agent_lock, NULL);
	pthread_mutex_init(&curl_buf_lock, NULL);
    pthread_mutex_init(&play_lock, NULL);
    pthread_mutex_init(&curl_lock, NULL);
    pthread_mutex_init(&token_lock, NULL);
	
	// 设置音频

	// result = RK_MPI_AMIX_SetControl(params->s32DevId, "I2STDM Digital Loopback Mode", "Mode2");//设置为双mic，一录一回采
    // if (result != RK_SUCCESS) {
    //     RK_LOGE("ai set I2STDM Digital Loopback Mode fail, reason = %x", result);
    //     goto __AICH_EXIT;
    // }
	for(int i=0;i<AMIX_MAX_NUM;i++){
		result = RK_MPI_AMIX_SetControl(AO_DEV_ID, g_ctx.amix[i][0], g_ctx.amix[i][1]);
		if (result != RK_SUCCESS) {
			RK_LOGE("amix set %s fail, reason = %x", g_ctx.amix[i][0], result);
		}
	}
	clifeSmartProductMirrorGetconfig();
	return 0;
}


int main(int argc, char *argv[])
{
	int i, item_cnt;
	pthread_t sock_tid;
	if (argc >= 2){
		clog_init((RK_CHAR *)"/tmp/log/gpt_client.log");
		clog_set_log_stdout(true);
		clog_set_log_fileout(false);
		clog_set_log_level(EM_LOG_INFO);
		rk_cmd_cli(argc, argv);
		return 0;
	}
	else{
		signal(SIGINT, signal_handler_int);
		signal(SIGQUIT, signal_handler_quit);
		clog_set_log_stdout(true);
		clog_set_log_fileout(false);
		clog_init((RK_CHAR *)"/tmp/log/gpt_server.log");
		clog_set_log_level(EM_LOG_INFO);
		pthread_create(&sock_tid, NULL, rk_cmd_server_command_func, NULL);
		pthread_join(sock_tid, NULL);
		//rk_cmd_server_command_func(NULL);
		HET_LOGI("%s quit!\r\n", __func__);
	}
	clog_exit();
	return true;
}